#include "Job.h"
#include <algorithm>
#include <utility>
#include <random>

Job::Job(std::vector<std::vector<int>> data, int serial) {
    this->serial = serial;
    this->n = data.size();
    this->m = data[0].size();
    this->costTime = data;
    // 初始顺序为0,1,...,n
    this->rank.resize(n);
    for (int i = 0; i < n; ++i) {
        this->rank[i] = i;
    }
    // 使初始序列随机化
    std::random_device rd;
    std::mt19937 gen(rd());
    std::shuffle(rank.begin(), rank.end(), gen);
}

Job::Job() = default;

int Job::makespan(std::vector<int> newRank) {
    std::vector<std::vector<int>> completeTime(n, std::vector<int>(m, 0));  // 记录机器加工完工件的时间
    completeTime[newRank[0]][0] = costTime[newRank[0]][0];  // 第一台机器加工完第一个工件花费的时间
    // 第一个工件被加工完的全部时间
    for (int i = 1; i < m; ++i) {
        completeTime[newRank[0]][i] = completeTime[newRank[0]][i - 1] + costTime[newRank[0]][i];
    }
    // 后续工件被加工完的时间
    for (int i = 1; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (j > 0) {
                completeTime[newRank[i]][j] = std::max(completeTime[newRank[i - 1]][j], completeTime[newRank[i]][j - 1]) + costTime[newRank[i]][j];
            }
            else {
                completeTime[newRank[i]][j] = completeTime[newRank[i - 1]][j] + costTime[newRank[i]][j];
            }
        }
    }
    // 返回最后一个工件在最后一台加工完成的时间
    return completeTime[newRank[n - 1]][m - 1];
}

std::vector<int> Job::getRank() {
    return this->rank;
}

void Job::setRank(std::vector<int> newRank) {
    this->rank = std::move(newRank);
}

int Job::getSerial() const {
    return this->serial;
}

size_t Job::getN() const {
    return this->n;
}

void Job::printRank() {
    for (auto iter: rank) {
        std::cout << iter << ' ';
    }
    std::cout << std::endl;
}
